/**************************************************************************
 * @doc EMV
 * @module EMVSrc |
 * Source code for the EMV handling functions.
 *
 * Product         :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team ASPAC ADC.
 * <nl>Notes       :
 *
 * @head3 EMV Functions |
 * @index | EMV
 * @end
 *
 * Copyright (c) 1996-2005 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
 *	Date						Author							Remarks
 *	13-Dec-2005		CHIA Lee Chyi				Modified function inEMVReferralProcessing for ETEC test case REQ02_05_01
 *
 ********************************************************************************/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#ifndef EMV_DEBUG  // to enalble TVRTSI
#define EMV_DEBUG
#endif

#include <project.h>
#define EMV_C

#include <sizes.h>
#include <aclconio.h>
#include <stdio.h>
#include <stdlib.h>
#include <acldev.h>
#include <aclstr.h>
#include <aclutil.h>
#include <prot8583.h>
#include <define.h>
#include <transact.h>
#include <dbmgr.h>
#include <mdlfuncs.h>
#include <svc.h>
#include <protocol.h>
#include <packet.h>
#include <tran.h>
#include <comm.h>
#include <modem.h>
#include <ppt.h>
#include <piputl.h>
#include <pipmsg.h>
#include <isoutl.h>
#include <isoload.h>
#include <ifldtbl.h>
#include <msg.h>
#include <msgfuncs.h>
#include <bdt.h>
#include <hdt.h>
#include <trt.h>
#include <mht.h>
#include <iit.h>
#include <accum.h>
#include <form.h>
#include <date.h>
#include <mem.h>
#include <spdebug.h>
#include <funcids.h>
#include <pbatch.h>
#include <errno.h>
#include <ascii.h>
#include <amexhost.h>
#include <pct.h>
#include <formater.h>
#include <table.h>
#include <string.h>
#include <confio.h>
#include <aclfile.h>
#include <format.h>
#include <spamsg.h>
#include <oper.h>
#include <batmsg.h>
#include <ui.h>
#include <tct.h>
#include <multilng.h>
#include <logo.h>
#include <settlbat.h>
#include <msgclrk.h>
#include <msgshf.h>
#include <menufunc.h>
#include <mit.h>
#include <applidl.h>
#include <tblutil.h>
#include <menus.h>
#include <Validt.h>
#include <stats.h>
#include <cardmsg.h>
#include <card.h>
#include <msg.h>
#include <define.h>
#include <entry.h>
#include <pinpad.h>
#include <ctype.h>
#include <gds.h>
#include <power.h>
#include <tip.h>
#include <iso8583.h>
#include <beetle.h>
#include <xmodem.h>
#include <modemmsg.h>
#include <rcptsegs.h>
#include <operate.h>
#include <amount.h>
#include <TCT.h>

#include <libvoy.h>
#include <cardslot.h>
#include <EMVCWrappers.h>
#include <common.h>

#include <vxemvap.h>
#include <emvlib.h>
#include <estfuncs.h>
#include <mvtfuncs.h>
#include <mvt.h>
#include <est.h>
#include <custsize.h>
#include <VXEMVAP_confproto.h>
//jrd one source
#ifdef __arm
#include <svc_sec.h>
#endif


#include "..\cpacsrc\cpacmsg.h"
#include "..\CPACSrc\custoper.h"

#include "..\citisrc\citimsg.h"

#include "EMVmsg.h"
#include "EMVsrc.h"
#include "EMVcall.h"
#include "d3des.h"
#include "APACSpin.h"
#include "EMVids.h"
#include "EMVsrcdef.h"

#include "..\..\Source\print\hostform.h"


struct spsales
{
    char panStr[21];
	char panSeqStr[3];
	char trnAmt[9];
};

struct spsales stSpsales;

//int con;
int pinSigRequired;
int pinStatus ; //edi - pin
byte *issuerScriptResults;
unsigned char CKclear[16];
unsigned char CKencr[16];
int masterKeyIndex;

int ppPresent;
int inPinTried;
unsigned char uchGblPinTryCtr;

extern unsigned long lnGlobalAmount;
extern int				hConsoleS;
extern EMV_CONFIG EMVGlobConfig ;
extern long lnTranTitleMessage;

extern char* szGetCPACTID(void);
extern int inImamLineNumber;
//KiaSoon 03022006 Started: To Fix AEIPS EDR44 Case
int inMenuFuncTried=0;
int inFirstSelect=1;
LABEL_REC srAPPLABEL;
//KiaSoon 03022006 Ended.

/********************************/
/* Internal Use for this EMVAPI */
/********************************/
//void vdPromptManager(int inCondition)
void vdPromptManager(unsigned short usCondition)
{
#ifdef EMV_DEBUG
    char outp[11];
    srTxnResult TVRTSI;
#endif
    char msg[22];


    memset(msg, 0, sizeof(msg));
    switch (usCondition)
    {
    	//case AUTO_CANCELLED:  //KiaSoon 03022006: To disable message on terminal -- AEIPS DR044 CASE
    	   // return;
        case TRANS_APPROVED:

            vdGetMessageFromFile(TRANS_APP_MSG,msg);
            //strcpy(msg, "Approved");
            break;
        case TRANS_DECLINED:
        	vdGetMessageFromFile(EMV_DECLINE_MSG21,msg);

            //strcpy(msg, "Declined");
            break;
        case OFFLINE_APPROVED:
        	vdGetMessageFromFile(EMV_OFFLINE_APPR_MSG,msg);
            //strcpy(msg, "Offline approved");
            break;
        case OFFLINE_DECLINED:
        	vdGetMessageFromFile(EMV_OFFLINE_DECLINE_MSG,msg);
           //strcpy(msg, "Offline declined");
            break;
        case OFFLINE_NOTALLOWED:
        	vdGetMessageFromFile(EMV_APP_NOT_AVAIL_MSG,msg);
           //strcpy(msg, "Not Accepted");
            break;
        case NONEMV:
        	vdGetMessageFromFile(EMV_NON_EMV_MSG,msg);
           //strcpy(msg, "Non EMV");
            break;
        case FAILURE:
        	vdGetMessageFromFile(EMV_FAILURE_MSG21,msg);
            //strcpy(msg, "Failure");
            break;
        case EMV_CHIP_ERROR:
        	vdGetMessageFromFile(EMV_CHIP_MALFUNCTION_MSG,msg);
            //strcpy(msg, "Emv chip error");
            break;
        case CARD_REMOVED:
        	vdGetMessageFromFile(EMV_CARD_REMOVED_MSG,msg);
            //strcpy(msg, "Card removed");
            break;
        case CARD_BLOCKED:
        	vdGetMessageFromFile(EMV_CARD_BLOCKED_BY_ISS_MSG,msg);
            //strcpy(msg, "Card blocked");
            break;
        case APPL_BLOCKED:
        	vdGetMessageFromFile(EMV_APP_BLOCKED_BY_ISS_MSG,msg);
            //strcpy(msg, "Appl blocked");
            break;
        case CANDIDATELIST_EMPTY:
        	vdGetMessageFromFile(EMV_CANDIDATE_LIST_EMPTY_MSG,msg);
            //strcpy(msg, "cand. list empty");
            break;
        case CHIP_ERROR:
        	vdGetMessageFromFile(EMV_CHIP_MALFUNCTION_MSG,msg);
            //strcpy(msg, "Chip error");
            break;
        case BAD_DATA_FORMAT:
        	vdGetMessageFromFile(EMV_BAD_DATA_FORMAT_MSG21,msg);
            //strcpy(msg, "Bad data format");
            break;
        case APPL_NOT_AVAILABLE:
        	vdGetMessageFromFile(EMV_APPL_NOT_AVAIL_MSG,msg);
            //strcpy(msg, "Appl not available");
            break;
        case TRANS_CANCELLED:
        	if(inFirstSelect==1)
        	   return;
        	vdGetMessageFromFile(EMV_TRANS_CANCELLED_MSG,msg);
            //strcpy(msg, "Trans cancelled");
            break;
        case EASY_ENTRY_APPL:
        	vdGetMessageFromFile(EMV_EE_APPL_MSG,msg);
            //strcpy(msg, "Easy entry appl");
            break;
        case ICC_DATA_MISSING:
        	vdGetMessageFromFile(EMV_CARD_DATA_MISSING_MSG,msg);
            //strcpy(msg, "Icc data missing");
            break;
        case CONFIG_FILE_NOT_FOUND:
        	vdGetMessageFromFile(EMV_CONFIG_NOT_PRESENT_MSG,msg);
            //strcpy(msg, "Config file not found");
            break;
        case FAILED_TO_CONNECT:
        	vdGetMessageFromFile(CONNECT_ERR_MSG,msg);
            //strcpy(msg, "Failed to connect");
            break;
        case SELECT_FAILED:
        	vdGetMessageFromFile(EMV_SELECT_FAILED_MSG,msg);
            //strcpy(msg, "Select failed");
            break;
        case USE_CHIP:
        	vdGetMessageFromFile(EMV_USE_CHIP_READER,msg);
            //strcpy(msg, "Use chip");
            break;
        case REMOVE_CARD:
        	vdGetMessageFromFile(EMV_PLS_REMOVE_CARD_MSG,msg);
            //strcpy(msg, "Please remove card");
            break;
        case BAD_ICC_RESPONSE:
        	vdGetMessageFromFile(EMV_BAD_ICC_RESP_MSG,msg);
            //strcpy(msg, "Bad ICC Resp");
            break;
	 case EMV_FAILURE:
			vdGetMessageFromFile(EMV_EMV_FAILURE_MSG,msg);
            //strcpy(msg, "Emv Failure");
            break;
		case USE_MAG_CARD:
			vdGetMessageFromFile(EMV_USE_MAG_STRIPE,msg);
            //strcpy(msg, "Use Mag Card");
            break;
		case TAG_NOTFOUND:
			vdGetMessageFromFile(EMV_TAG_NOTFOUND_MSG21,msg);
            //strcpy(msg, "Tag Not Found");
            break;

              case INVALID_PARAMETER:
              	vdGetMessageFromFile(EMV_INVALID_PARAM_MSG21, msg);
              	break;
              case TAG_NOT_SUPPORTED:
              	vdGetMessageFromFile(EMV_TAG_NOT_SUPPORTED_MSG, msg);
              	break;
              case TAG_ALREADY_PRESENT:
              	vdGetMessageFromFile(EMV_TAG_ALREADY_PRESENT_MSG21, msg);
              	break;

              case E_INVALID_LENGTH:
		case 0x6400:
		case 0x6985:
		case 0x6300:
        	case 0x63C0:
		case 0x63C1:
		case 0x63C2:
		case 0x63C3:
        	case 0x6A83:
		case 0x6A88:
		case 0x6700:
		case 0x6E00:
		case 0x6D00:
			vdGetMessageFromFile(EMV_FAILURE_MSG21, msg);
			break;
        default:
            strcpy(msg, "FAIL");
            break;
    }

     //This is being done before printing the receipt
    /*if (pinSigRequired)
        write_at("Signature required", 18, 1, 5);*/

	{//Alona Suggestion
		char szTVRTrace[2];
		szTVRTrace[get_env("EMV.TVRTRC", szTVRTrace, 1)] = NULL_CH;
		if (szTVRTrace[0] == '1') {
#ifdef EMV_DEBUG
			usEMVGetTxnStatus(&TVRTSI);
			hex_2_asc((byte *) outp, TVRTSI.stTVR, 5);
			outp[10] = '\0';
			write_at("TVR ", 4, 1, inImamLineNumber-2);
			write_at(outp, 10, 5, inImamLineNumber-2);
			shSpool(&obPrinter, "TVR:");
			shSpool(&obPrinter, "\n----\n");
			shSpool(&obPrinter, outp);
			shSpool(&obPrinter, "\n----\n");

			hex_2_asc((byte *) outp, TVRTSI.stTSI, 2);
			outp[4] = '\0';
			write_at("TSI ", 4, 1, inImamLineNumber-1);
			write_at(outp, 4, 5, inImamLineNumber-1);
			shSpool(&obPrinter, "TSI:");
			shSpool(&obPrinter, "\n----\n");
			shSpool(&obPrinter, outp);
			shSpool(&obPrinter, "\n----\n\n\n\n\n\n");
#endif /* EMV_DEBUG */
		}
	}

    //write_at(msg, strlen(msg), 1, 8);
    //vdDelay(PROMPT_DELAY);
    //error_tone();
    
    vdCustDisplayErrorString(msg);
    }

//void vdPromptRemoveManager(int inCondition)
void vdPromptRemoveManager(unsigned short usCondition)
{
#ifdef EMV_DEBUG
    char outp[11];
    srTxnResult TVRTSI;
#endif
    char msg[22];


    memset(msg, 0, sizeof(msg));
    switch (usCondition)
    {
        case REMOVE_CARD:
            //strcpy(msg, "Please remove card");
            vdGetMessageFromFile(EMV_PLS_REMOVE_CARD_MSG,msg);
            break;
	default:
            //strcpy(msg, "Please remove card");
            vdGetMessageFromFile(EMV_PLS_REMOVE_CARD_MSG,msg);
            break;
    }

	 //This is being done before printing the receipt
    /*if (pinSigRequired)
        write_at("Signature required", 18, 1, 5);*/

	{//Alona Suggestion
		char szTVRTrace[2];
		szTVRTrace[get_env("EMV.TVRTRC", szTVRTrace, 1)] = NULL_CH;
		if (szTVRTrace[0] == '1') {
#ifdef EMV_DEBUG
			usEMVGetTxnStatus(&TVRTSI);
			hex_2_asc((byte *) outp, TVRTSI.stTVR, 5);
			outp[10] = '\0';
			write_at("TVR ", 4, 1, inImamLineNumber-2);
			write_at(outp, 10, 5, inImamLineNumber-2);
			shSpool(&obPrinter, "FINAL TVR-TSI\n");
			shSpool(&obPrinter, "TVR: ");
			shSpool(&obPrinter, outp);
			shSpool(&obPrinter, " \n");

			hex_2_asc((byte *) outp, TVRTSI.stTSI, 2);
			outp[4] = '\0';
			write_at("TSI ", 4, 1, inImamLineNumber-1);
			write_at(outp, 4, 5, inImamLineNumber-1);
			shSpool(&obPrinter, "TSI: ");
			shSpool(&obPrinter, outp);
			shSpool(&obPrinter, "\n----\n\n\n\n\n\n");
#endif /* EMV_DEBUG */
		}
	}

    write_at(msg, strlen(msg), 1, inImamLineNumber);
    vdDelay(PROMPT_DELAY);
    error_tone();
    //vdCustDisplayErrorString(msg);
}



int inDisplayOverrideChipScrn(void)
{
	char chAnswer;

   	vdClearNonTitleLines();
	chAnswer = (char)obDisp.inDO_ChooseOne(NULL,(char *)pchGetMsg(EMV_OVERRIDE_CHIP_MSG1), (char *)pchGetMsg(YESNO_MSG5x), 2, NULL_PFI);

       if(chAnswer == KEY_NO)
        	return VS_ERR;
       else if (chAnswer == KEY_YES)
        	return VS_SUCCESS;
	return VS_SUCCESS;
 }


void    vdEMVDisplayErrorMsg(EMVResult val)
{
long lnMessage = 0L;

    switch(val)
	{

	case E_CHIP_ERROR:
		lnMessage = EMV_CHIP_MALFUNCTION_MSG;
		// Display details of chip error if appropriate
		break;

	case E_BAD_ICC_RESPONSE:
	    lnMessage = EMV_CANNOT_COM_CARD_MSG;

		// Display "CANNOT COMUNICATE WITH CARD"
		break;

	case E_CARD_REMOVED:
	    lnMessage = EMV_CARD_REMOVED_MSG;

		// Display "CARD REMOVED"
		break;

	case E_ICC_BLOCKED:
	    lnMessage = EMV_CARD_BLOCKED_BY_ISS_MSG;

		// Display "CARD BLOCKED BY ISSUER"
		break;

	case 0x6283:
	    lnMessage = EMV_APP_BLOCKED_BY_ISS_MSG;

		// Display "APPLICATION BLOCKED BY ISSUER"
		break;

	case E_CANDIDATELIST_EMPTY:
	    lnMessage = EMV_CARD_NOT_SUPPORTED_MSG;

		// Display "THIS CARD NOT SUPPORTED"
		break;

	case E_ICC_DATA_MISSING:
	    lnMessage = EMV_CARD_DATA_MISSING_MSG;

		// Display "CARD DATA MISSING"
		break;

	case 0x6985:
	    lnMessage = EMV_APP_NOT_AVAIL_MSG;

		// Display "NOT ACCEPTED"
		break;

	case E_TLVFORMAT:
	    lnMessage = EMV_INVALID_DATA_MSG;

		// Display "INVALID DATA FROM CARD"
		break;

	case EMV_FAILURE:
	    lnMessage = EMV_FAILURE_MSG21;
		break;
	case EMV_SIGNATURE:
	    lnMessage = EMV_SIGNATURE_MSG21;
		break;
	case EMV_ONLINE_PIN:
	    lnMessage = EMV_ONLINE_PIN_MSG21;
		break;

	case E_TRANS_CANCELLED:
	    lnMessage = EMV_TRANS_CANCELLED_MSG;
		break;
	case E_NONE_COMMON:
	    lnMessage = EMV_NONE_COMMON_MSG21;
		break;
	case E_INVALID_PARAM:
	    lnMessage = EMV_INVALID_PARAM_MSG21;
		break;
	case E_INVALID_APP:
	    lnMessage = EMV_INVALID_APP_MSG21;
		break;
	case E_DO_ABSENT:
	    lnMessage = EMV_DO_ABSENT_MSG21;
		break;
	case E_DO_REPEAT:
	    lnMessage = EMV_DO_REPEAT_MSG21;
		break;
	case E_INVALID_PIN:
	    lnMessage = EMV_INVALID_PIN_MSG21;
		break;

	case E_PIN_LAST_CHANCE:
	    lnMessage = EMV_PIN_LAST_CHANCE_MSG21;
		break;
	case E_PIN_RETRYLIMIT:
	    lnMessage = EMV_PIN_RETRYLIMIT_MSG21;
		break;
	case E_GO_OFFLINE:
	    lnMessage = EMV_GO_OFFLINE_MSG21;
		break;
	case E_GO_ONLINE:
	    lnMessage = EMV_GO_ONLINE_MSG21;
		break;
	case E_DECLINE:
	    lnMessage = EMV_DECLINE_MSG21;
		break;
	case E_INVALID_SEQUENCE:
	    lnMessage = EMV_INVALID_SEQUENCE_MSG21;
		break;

	case E_TLVCOLLECTION_FULL:
	    lnMessage = EMV_TLVCOLLECTION_FULL_MSG21;
		break;
	case E_INVALID_PDOL:
	    lnMessage = EMV_INVALID_PDOL_MSG21;
		break;
	case E_INVALID_CDOL:
	    lnMessage = EMV_INVALID_CDOL_MSG21;
		break;
	case E_INVALID_TDOL:
	    lnMessage = EMV_INVALID_TDOL_MSG21;
		break;
	case E_INVALID_DDOL:
	    lnMessage = EMV_INVALID_DDOL_MSG21;
		break;
	case E_SDA_FAILED:
	    lnMessage = EMV_SDA_FAILED_MSG21;
		break;
	case E_DDA_FAILED:
	    lnMessage = EMV_DDA_FAILED_MSG21;
		break;
	case E_AID_LIST_FULL:
	    lnMessage = EMV_AID_LIST_FULL_MSG21;
		break;
	case ICC_PSE_NOT_FOUND:
	    lnMessage = ICC_PSE_NOT_FOUND_MSG21;
		break;

	case E_6A02_FORMAT:
	    lnMessage = EMV_6A02_FORMAT_MSG21;
		break;
	case E_6A03_FORMAT:
	    lnMessage = EMV_6A03_FORMAT_MSG21;
		break;
	case E_6A04_FORMAT:
	    lnMessage = EMV_6A04_FORMAT_MSG21;
		break;
	case E_6A05_FORMAT:
	    lnMessage = EMV_6A05_FORMAT_MSG21;
		break;
	case E_0x6983:
	    lnMessage = EMV_0x6983_MSG21;
		break;
	case E_0x6984:
	    lnMessage = EMV_0x6984_MSG21;
		break;
	case E_HASH_FAILED:
	    lnMessage = EMV_HASH_FAILED_MSG21;
		break;
	case E_PAN_FAILED:
	    lnMessage = EMV_PAN_FAILED_MSG21;
		break;
	case E_CERTIFICATE_EXPIRED:
	    lnMessage = EMV_CERTIFICATE_EXPIRED_MSG21;
		break;
	case E_HASHALGO:
	    lnMessage = EMV_HASHALGO_MSG21;
		break;
	case E_IPKALGO:
	    lnMessage = EMV_IPKALGO_MSG21;
		break;
	case E_9F37_ABSENT:
	    lnMessage = EMV_9F37_ABSENT_MSG21;
		break;

	case E_DIFF_AVN_ERR:
	    lnMessage = EMV_DIFF_AVN_ERR_MSG21;
		break;
	case E_SERVICE_NOT_ALLOWED:
	    lnMessage = EMV_SERVICE_NOT_ALLOWED_MSG21;
		break;
	case E_APP_NOTYET_EFFECTIVE:
	    lnMessage = EMV_APP_NOTYET_EFFECTIVE_MSG21;
		break;
	case E_APP_EXPIRED:
	    lnMessage = EMV_APP_EXPIRED_MSG21;
		break;
	case E_TXN_RAND_SELECT:
	    lnMessage = EMV_TXN_RAND_SELECT_MSG21;
		break;
	case E_TXN_OVER_FLOOR:
	    lnMessage = EMV_TXN_OVER_FLOOR_MSG21;
		break;
	case E_UPPER_LOWER_LMT_EXCEED:
	    lnMessage = EMV_UPPER_LOWER_LMT_EXCEED_MSG21;
		break;
	case E_LOWER_LMT_EXCEED:
	    lnMessage = EMV_LOWER_LMT_EXCEED_MSG21;
		break;
	case E_UPPER_LMT_EXCEED:
	    lnMessage = EMV_UPPER_LMT_EXCEED_MSG21;
		break;
	case E_NEW_CARD:
	    lnMessage = EMV_NEW_CARD_MSG21;
		break;
	case E_CVM_FAILED:
	    lnMessage = EMV_CVM_FAILED_MSG21;
		break;
	case E_PINPAD_ABSENT:
	    lnMessage = EMV_PINPAD_ABSENT_MSG21;
		break;
	case E_PIN_REQD_ABSENT:
	    lnMessage = EMV_PIN_REQD_ABSENT_MSG21;
		break;
	case E_UNRECOGNIZED_CVM:
	    lnMessage = EMV_UNRECOGNIZED_CVM_MSG21;
		break;
	case E_CVM_PASSED:
	    lnMessage = EMV_CVM_PASSED_MSG21;
		break;
	case E_BAD_DATA_FORMAT:
	    lnMessage = EMV_BAD_DATA_FORMAT_MSG21;
		break;
	case E_BAD_HASHALGO:
	    lnMessage = EMV_BAD_HASHALGO_MSG21;
		break;
	case E_BAD_IPKALGO:
	    lnMessage = EMV_BAD_IPKALGO_MSG21;
		break;
	case E_STATWORD_WARNING:
	    lnMessage = EMV_STATWORD_WARNING_MSG21;
		break;
	case E_STATWORD_NORMAL:
	    lnMessage = EMV_STATWORD_NORMAL_MSG21;
		break;
	case E_SCRIPTPROCFAILBEFORE_GENAC:
	    lnMessage = EMV_SCRIPTPROCFAILBEFORE_GENAC_MSG21;
		break;
	case E_SCRIPTPROCFAILAFTER_GENAC:
	    lnMessage = EMV_SCRIPTPROCFAILAFTER_GENAC_MSG21;
		break;

	case E_INVALID_LENGTH:
	    lnMessage = EMV_INVALID_LENGTH_MSG21;
		break;
	case E_TAG_NOTFOUND:
	    lnMessage = EMV_TAG_NOTFOUND_MSG21;
		break;
	case E_NO_MORE_TLV:
	    lnMessage = EMV_NO_MORE_TLV_MSG21;
		break;
	case E_INVALID_OFFSET:
	    lnMessage = EMV_INVALID_OFFSET_MSG21;
		break;
	case E_BAD_COMMAND:
	    lnMessage = EMV_BAD_COMMAND_MSG21;
		break;
	case E_TAG_ALREADY_PRESENT:
	    lnMessage = EMV_TAG_ALREADY_PRESENT_MSG21;
		break;
	case E_READ_RECORD_FAILED:
	    lnMessage = EMV_READ_RECORD_FAILED_MSG21;
		break;
	case E_INVALID_SDOL:
	    lnMessage = EMV_INVALID_SDOL_MSG21;
		break;
	case E_EXPLICIT_SELEC_REQD:
	    lnMessage = EMV_EXPLICIT_SELEC_REQD_MSG21;
		break;
	case E_COND_NOT_SATISFIED:
	    lnMessage = EMV_COND_NOT_SATISFIED_MSG21;
		break;

	default:
	    lnMessage = EMV_ERROR_UNKNOWN_MSG;
		break;
	}
    if (lnMessage != 0L)
    {
        clrscr();
        vdDisplayMessageFromFile(lnMessage, ERROR_MSG);
    }
    vdFlushKeyboardBuffer();

}

void vdDisplayFallbackMsg(TRANSACTION_OBJECT *pobTran)
{
	//if ((pobTran->szServiceCode[0] == '2') || (pobTran->szServiceCode[0] == '6'))
	//{	// Service code exists and the first digit is '2' or '6'
		if(inGetFallbackAllowedFlag())
			{

			vdDisplayWarningMsg(EMV_USE_MAG_STRIPE);
			}
	//}

	return;
}

int createScriptFiles(byte *buffer)
{
	byte *ptr;
	byte data[128];
	unsigned int tag;
	int bufLen;
	int h1, h2, handle;
	int bytesRead;
	int bytes;
	int numScripts;
	char szScriptFName71 [FILENAME_SIZE + 1];
	char szScriptFName72 [FILENAME_SIZE + 1];

	bufLen = buffer[1];
	ptr = &buffer[0];                                                  // Start of data section
	handle = 0;

	vdGetEMVS71FName(szScriptFName71);
	vdGetEMVS72FName(szScriptFName72);
	h1 = open(szScriptFName71, O_CREAT | O_WRONLY);
	h2 = open(szScriptFName72, O_CREAT | O_WRONLY);
	bytes = 0;
	bytesRead = 0;
	numScripts = 0;
	do
	{
		//        bytes = getNextRawTLVData(&tag, data, ptr + bytesRead);
		bytes = getNextRawTLV(&tag, data, ptr + bytesRead);
		bytesRead += bytes;
		if (tag == 0x71)
		    handle = h1;
		else if (tag == 0x72)
		    handle = h2;
		if (handle)
		{
		    numScripts++;
		    write(handle, (char *) data, bytes);
		    handle = 0;
		}
	} while (bytesRead < bufLen);
	close(h1);
	close(h2);

	return (numScripts);
}


EMVBoolean bIsCardBlackListed(byte * pan, unsigned short panLen, byte * panSeqNo, unsigned short panSeqLen)
{

    char panStr[21] = {0};
	char panSeqStr[3] = {0};
	char buf[25] = {0};
    char panRead[21] = {0};
	char panseqRead[3] = {0};

	int fHandle = 0;
	int retVal = 0;
	int noOfBytes = 0;

	char * pSeploc;

	hex_2_asc((byte *) panStr, pan, panLen);
	hex_2_asc((byte *) panSeqStr, panSeqNo, panSeqLen);

	fHandle = open ("BlackListedCards.txt", O_RDONLY);

 	if(fHandle < 0)
 	    return(EMV_FALSE);

     memset(buf, 0x00, sizeof(buf));

     retVal = readRecord(fHandle, buf);

     //check for read() returning 0 for EOF.
     while(retVal != 0)
     {
             //get the card type
       //  noOfBytes = parseRecord(buf, 1, ',', temp);

		if( (pSeploc = strchr( buf, ',' )) != NULL)
		{
			memcpy(panRead,buf, (pSeploc-buf));
			memcpy(panseqRead, &buf[pSeploc-buf+1],2);

			if( !(memcmp (panStr,panRead,strlen(panStr))))
				if( !(memcmp (panSeqStr,panseqRead,strlen(panSeqStr))))
				{
					close (fHandle);
					return(EMV_TRUE);
				}
		}

         //CodeReview-18-Dec-2002
         //		Added this piece of code because the while loop would never end if
		//	    we didn't read the file again.
         retVal = readRecord(fHandle, buf);

         if(retVal == EMV_FALSE)
         {
         	close(fHandle);
              return(retVal);
         }
     } //end of while

     close (fHandle);

	return (EMV_FALSE);
}

char inGetOption(void)
{
    char key;

    key = chGetKeyPress();
    while ((key != 1) && (key != 2))
        key = chGetKeyPress();

    return (key);
}

short shGetAutoSelectFlag(void)
{
    char key;

    clrscr();
    write_at("User application", 16, 1, 1);
	write_at("selection?", 10, 1, 2);
	if (inImamLineNumber == 16){
		write_at("Yes", 3, 19, 4);
		write_at("No", 2, 20, 7);
	} else {
		write_at("Yes", 3, 19, 1);
		write_at("No", 2, 20, 3);
	}

    key = inGetOption();
    if (key == 1)
        return 0;   // User selection.
    else
        return 1;   // Auto selection.
}

int inMenuFunc(char **labels, int numLabels)
{
    int  i = 0;
    int  j;
    int  k; //KiaSoon Mapped Menu
    char nextKey = 0;
    char prevKey = 0;
    char menuKeys[4];
    char key;
    long lnAnswer = 0L;
    int numMapLabels;

	/* KiaSoon 03022006:  To fix AEIPS EDR044 Problem. This function modified to allow only first time call. 
			      Will genenate a map to indicate which function has been selected before and exclude them 
			      in the label file.*/
	if(inFirstSelect)
		vdInitLabelTable(numLabels);
	
	if(inMenuFuncTried !=0)
		return (TRANS_CANCELLED); 
	
	vdGenerateMap(numLabels);
	numMapLabels=inRtrnMenuLabel(numLabels);
	/* KiaSoon 03022006 Ended */
	
	while (1)
	{
		clrscr();
		memset(menuKeys, 0, 4);
		nextKey = 0;
		prevKey = 0;

		j = 0;
		while (j < MAX_MENU_ITEMS)
		{
			//if ((i + j) >= numLabels)
			if ((i + j) >= numMapLabels)//KiaSoon 03022006: To fix AEIPS EDR044 
				break;
			else
			{
				menuKeys[j] = 1;
                		//write_at(labels[i + j], strlen(labels[i + j]), 1, ((j * 2) + 1));
                		//vdDispStrAtRight(labels[i+j], ((j * 2) + 1), CLR_EOL);//To display the message on the right side of the screen
                		//KiaSoon 03022006: To fix AEIPS EDR044 
                		k=inRtrnOriginalLabel(i+j+1);
						if (inImamLineNumber==16){
							vdDispStrAtRight(labels[k-1], ((j * 3) + 4), CLR_EOL);
						} else {
                			vdDispStrAtRight(labels[k-1], ((j * 2) + 1), CLR_EOL);//To display the message on the right side of the screen
						}
                		//KiaSoon Ended
               		}
			j++;
		}

        // No. of labels on screen is now j
		//if ((i + j) < numLabels)
		if ((i + j) < numMapLabels)//KiaSoon 03022006: To fix AEIPS EDR044 
			nextKey = 1;
		else
			vdDisplayMessageFromFile(EMV_PLS_CONFIRM_MSG, STATUS_MSG);

		if (i)
			prevKey = 1;

		if (nextKey)
			vdDisplayAt(13, inImamLineNumber, "NEXT", NO_CLEAR);
	            //write_at("NEXT", 4, 18, 8);

		if (prevKey)
			vdDisplayAt(1, inImamLineNumber, "PREV", NO_CLEAR);
	            //write_at("PREV", 4, 13, 8);

        //key = chGetKeyPress();
        key = inWaitKey(inGetIdleTimeOut());

        if (key == KEY_c)
		{	// Next
			if (nextKey)
				i += MAX_MENU_ITEMS;
			else
				error_tone();
		}
		else
			if (key == KEY_a)
			{	// Previous
				if (prevKey)
					i -= MAX_MENU_ITEMS;
				else
					error_tone();
			}
			else
				if (key >= KEY_e && key <= KEY_h)
				{	// Menu selection
					if (menuKeys[key - KEY_e]){
						//KiaSoon 03022006 Started: for AEIPS DR044
						inMenuFuncTried=1; 
						LOG_PRINTFF((0x8L, "inMenuFunc-Select=%d",(i + (key - KEY_e) + 1))); 
						k=inRtrnOriginalLabel(i + (key - KEY_e) + 1);
						vdSetApplLabelSelect(k);
						return k;
						//return(i + (key - KEY_e) + 1);
						//KiaSoon Ended
					}
					else
						error_tone();
				}
				else
					if (key == KEY_CANCEL){
						inFirstSelect=2;
						return (TRANS_CANCELLED);
					}
					else
					    error_tone();
	}
}


unsigned short usAmtEntryFunc(unsigned long *lnAmountValue)
{
    char szAmount[AMT_SIZE + 1];
    int  inResult;
    int  inOpenAmount;
    char *szDisplaySymbol;
    char szDisplayBuffer[DISP_STR_LEN + 1];
    inOpenAmount = 0;

    lnGlobalAmount = 0;
    memset(szAmount, 0x00, sizeof (szAmount));
    vdDisplayMessageFromFile( AMT_MSG, ENTRY_MSG);
    szAmount[0] = '\0';

    szDisplaySymbol = szGetCurSymbol();
    vdGetMessageFromFile(AMT_MSG, szDisplayBuffer);
    BT_TRACE ('I', szDisplayBuffer);
    if ((inResult = inGetAmount(szAmount, VS_TRUE, 1L, 999999999L, szDisplaySymbol)) != VS_SUCCESS)
        return(inResult);

    (*lnAmountValue) = lnGlobalAmount = atol(szAmount);
    return (EMV_SUCCESS);  //????KF long value putting to a short value.....
}

void vdSetCDTSignLine(VS_BOOL fSignLine)
{
    vdSetSignLine(fSignLine);
}

int readRecord(int fHandle , char *buf)
{

    char readBytes = 0;
    int retVal;
    int i = 0;

    while(readBytes != '\r')
    {
        retVal = read(fHandle, &readBytes, 1);
        if(retVal == 0)
               return 0 ;
		if(readBytes != '\n')
			buf[i++] = readBytes;

        if(retVal < 0)
	    {
		    close(fHandle);
		    return(EMV_FALSE);
	    }
    }
    buf[i] = '\0';

    //memcpy(buf, readBytes, count);

    return (i);

}

char chConvertKey(char key)
{
    if ((unsigned char) key > 0xf9)
        key -= 0xf9;                    // Screen keys fa-fd -> 1-4
	else if ((unsigned char) key < 0xef)
        key &= 0x7f;	                // Keypad keys 0-ef -> 0-7f

	return key;
}


char chGetKeyPress(void)
{
    int len;
    char key;

    vdFlushKeyboard();

    while (1)
    {
        if (wait_event() & EVT_KBD)
        {
            //len = read(con, &key, 1);
            len = read(hConsoleS, &key, 1);
            break;
        }
    }
    key = chConvertKey(key);

    return (key);
}


void vdFlushKeyboard(void)
{
    int len;
    char key[20] = {0}; //Char is changed to an Array.Ravi_b3

    //len = read(con, key, 20);
     len = read(hConsoleS, key, 20);
}

int inEMVPPcom(char *command, char *answer, char complex)
{
	int retVal;
	struct Opn_Blk xcomblock;
	unsigned char msg[256+1];
	int i,j;
	int RepSend;
	int RepRec;
	int stxok;
	int etxok;
	int ackok;
	int nakok;
	int loops;
	int len;
	int ok;
	char chr;
	char end;
	int xcom;

	//char strout[30];
	//int con = open(DEV_CONSOLE, O_RDWR);

	retVal=RERROR;
	xcom = open(DEV_COM2, O_RDWR);
	xcomblock.rate = Rt_1200;
	xcomblock.format = Fmt_A7E1;
	xcomblock.protocol = P_char_mode;
	set_opn_blk(xcom,(struct Opn_Blk *)(& xcomblock));

	loops=0;
	RepSend=1;
	while(RepSend<4)
		{
		if(loops>MAX_LOOPS) return(RERROR);
		command[i=strlen(command)]=LRC(&command[1], strlen(command)-1);
		command[i+1]=0;
		write(xcom, command, strlen(command));
		stxok=-1;
		etxok=-1;
		ackok=-1;
		nakok=-1;
		i=0;
		j=0;
		RepRec=1;
		while(RepRec<4)
			{
			if(loops>MAX_LOOPS) return(RERROR);
			SVC_WAIT(300);
			i=0;
			memset(msg, 0x00, 256+1);
			ok=1;
			len=0;
			while((ok) && (i<256))
				{
				if(j>1000) return(RERROR);		//timeout
				SVC_WAIT(30);
				read(xcom, (char *)&msg[i], 1);
				if(msg[i]!=0)
					{
					len++;
					switch(msg[i])
						{
						case NAK:
							end=1;
							nakok=i;
							break;
						case ETX:
						case SO:
							etxok=i;
							ok=0;
							read(xcom, (char *)&msg[i+1], 1);
							len++;
							break;
						case STX:
						case SI:
							j=0;
							stxok=i;
							break;
						case ACK:
							j=0;
							ackok=i;
							if(!complex) ok=0;
							break;
						}

					i++;
					}
				j++;
				}

			if(len>0)
				{
				chr=0;

				//sprintf(strout,"\r\ns%2.2d|e%2.2d|a%2.2d|n%2.2d|l%2.2d",stxok,etxok,ackok,nakok,len);
				//write(con, strout, strlen(strout));
				//while(!(wait_event()& EVT_KBD));

				if(nakok>=0)
					{
					RepRec=4;
					RepSend++;
					chr=0;
					}
				if(ackok>=0)
					if(stxok>=0)
						if(etxok>=0)
							{
							if(LRC((char *)&msg[stxok+1], etxok-stxok)==msg[etxok+1])
								{
								strcpy(answer, (char *)&msg[stxok]);
								RepRec=4;
								RepSend=4;
								chr=ACK;
								retVal=ROK;
								}
							else
								{
								RepRec++;
								chr=NAK;
								}
							}
						else
							{
							RepRec++;
							chr=NAK;
							}

					else
						{
						RepRec=4;
						RepSend=4;
						retVal=ROK;
						chr=0;
						}
				}
			if(chr!=0) write(xcom, &chr, 1);
			loops++;
			}
		loops++;
		}

	SVC_WAIT(200);
	close(xcom);
	return(retVal);
}

int inEMVPPPresent(void)
{
	int retVal=RERROR;
	char tmp[10];
	memset(tmp, 0, 10);

	sprintf(tmp, "%c11%c", SI, SO);
	if(inEMVPPcom(tmp, tmp, 0)==ROK)
		//if(tmp[0]==ACK)
			retVal=ROK;

	return(retVal);

}


short getPPUsrPin(unsigned char * pstPin, unsigned char *CKclear, unsigned char *CKencr, int *index)
{
	static unsigned char tag9F41_prev[4];	/*transaction sequence counter*/
	static unsigned char tag5A_prev[10+1];	/*PAN*/
	static unsigned char tag9F17_prev[2];		/*PIN try counter*/
	unsigned char tag9F41_curr[4];			/*transaction sequence counter*/
	unsigned char tag5A_curr[10+1];		/*PAN*/
	unsigned char tag9F17_curr[2];			/*PIN try counter*/
	long amt1, amt2;
	double amt=0;
	char msg1[16+1];
	char msg2[16+1];
	char msg3[16+1];
	unsigned short taglen;
	char buff[256];

	amt1=12345;
	amt2=0;
	//usEMVGetTLVFromColxn(0x8100, (unsigned char*) amt1, 4);
	//usEMVGetTLVFromColxn(0x9F04, (unsigned char*) amt2, 4);

	//amt=amt1/100;
	//sprintf(msg1, "%.2f", amt);
	strcpy(msg1,ENTER_YOUR_PIN);
	strcpy(msg2,ENTER_YOUR_PIN);
	strcpy(msg3,PLEASE_WAIT);
	taglen=0;
	if(usEMVGetTLVFromColxn(0x9f41, tag9F41_curr, &taglen)==EMV_SUCCESS){
		memset(buff, 0x00, sizeof(buff));
		if (taglen<128) hex_2_asc((BYTE *)buff, tag9F41_curr, taglen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x9f41, buff));
	}
	if(usEMVGetTLVFromColxn(0x5a00, tag5A_curr, &taglen)==EMV_SUCCESS){
		memset(buff, 0x00, sizeof(buff));
		if (taglen<128) hex_2_asc((BYTE *)buff, tag5A_curr, taglen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5a00, buff));
	}
	//if(usEMVGetTLVFromColxn(0x0f17, tag9F17_curr, &taglen)==EMV_SUCCESS);
	if(usEMVGetTLVFromColxn(0x9f17, tag9F17_curr, &taglen)==EMV_SUCCESS){
		memset(buff, 0x00, sizeof(buff));
		if (taglen<128) hex_2_asc((BYTE *)buff, tag9F17_curr, taglen);
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x9f17, buff));
	}

	if(memcmp(tag9F41_curr, tag9F41_prev, 2)==0)
		if(memcmp(tag5A_curr, tag5A_prev, 8)==0)
			//the same transaction, next call
			switch(tag9F17_curr[0])
				{
				case 0:
					//card blocked
					pstPin[0]=0;
					return(0);
				case 1:
					//last pin try
					strcpy(msg1, LAST_PIN_TRY);
					break;
				default:
					strcpy(msg1, INCORRECT_PIN);
					break;
				}



	tag9F17_prev[0]=tag9F17_curr[0];
	memcpy(tag5A_prev, tag5A_curr, 8);
	memcpy(tag9F41_prev, tag9F41_curr, 2);

	return(inEMVGetPin((char *)pstPin, (char *)CKencr, (char *)CKclear, *index, msg1, msg2, msg3));
}

int inEMVGetPin(char *buffer, char *key, char *mk, int index, char *msg1, char *msg2, char *msg3)
{
	/*buffer - plain text pin buffer*/
	/*key - encrypted key value 0's if PP MK is used as CK*/
	/*mk - clear key value*/
	/*index - index of PP MK used to encrypt key*/
	/*msg1 - first message*/
	/*msg2 - second message*/
	/*msg3 - processing message*/

	int retVal=0;
	//int xcom;
	int i;
	//int con = open(DEV_CONSOLE, O_RDWR);
	unsigned char tmp[50];
	char stxok;
	//char chr;
	//char encr[16+1];
	char PAN[16+1];
	int rep;
	unsigned char msg[256+1];

	get_unpredict(tmp, 8);
	sprintf(PAN, "%02.02d%02.02d%02.02d%02.02d%02.02d%02.02d%02.02d%02.02d",
		tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7]);
	PAN[16]=0;
	sprintf((char *)msg,"%c08%1.1d%c",SI, (char)index, SO);
	if(inEMVPPcom((char *)msg, (char *)msg, 0)!=ROK)
		return(RERROR);
	SVC_WAIT(50);
	stxok=0;
	rep=1;
	memset(msg, 0x00, 256+1);
	//sprintf(msg,"%c70.%8.19s%c%16.16s000%c",STX, PAN, FS, key, ETX);
	sprintf((char *)msg, "%cZ62.%8.19s%c%16.16s0412Y%0.16s%c%0.16s%c%0.16s%c",
	STX, PAN, FS, key, msg1, FS, msg2, FS, msg3, ETX);
	retVal=inEMVPPcom((char *)msg, (char *)msg, 1);
	SVC_WAIT(50);
	sprintf((char *)msg,"%cQ2%c", STX, ETX);
	if(retVal==ROK) retVal=inEMVPPcom((char *)msg, (char *)msg, 0);
	if(retVal==ROK)
		{
		if(msg[9]==ETX)
			return(0);	/*no pinblock=pin entry canceled*/
		ascii_to_bin(tmp, (unsigned char *)mk, 16);
		deskey(tmp, 1);
		ascii_to_bin(tmp, &msg[9], 16);
		des(tmp, tmp);

		memset(&tmp[8], 0x00, 8);
		ascii_to_bin(&tmp[8+2], (unsigned char *)&PAN[strlen(PAN)-12-1], 12);
		for(i=0;i<8;i++) tmp[i]^=tmp[i+8];
		if(tmp[0]>12) tmp[0]=12;
		hex_2_asc((unsigned char *)buffer, &tmp[1], (int)(tmp[0]/2)+1);
		buffer[tmp[0]]=0;
		retVal=tmp[0];	/*pin lenght*/
		}
	else
		retVal=0;
	return(retVal);
}

int   inPINValidator(char *pstPIN)
{
	// Make sure PIN has at least 4 chars
	if (strlen(pstPIN) < 4)////ivan added to do  pin bypass
	{
		if(fGetPINBypass() == VS_TRUE)
		{
			if (strlen(pstPIN) == 0)
			{
				return(VS_SUCCESS);
			}
			else
			{
				vdSGErrorMessage(INVALID_ENTRY_MSG);
				return(VS_ERR);
			}
		}
		else
		{
			vdSGErrorMessage(INVALID_ENTRY_MSG);
			return(VS_ERR);
		}


        }
	else
		return(VS_SUCCESS);



}

typedef int (*PFI_TO_GET_PIN)(long lnMessageNumber, VS_BOOL fScrollDisplay, char *szResponseString,
    int inDataType, int inMaxChars, int  (*inValidator)(char *szResponseString)); //Function pointer defined for EMV_GET_USER_PIN //K_F2
short getTermUsrPin(unsigned char *pin)
{

/*
    char str[13];  // Array size increased to accomadate 12 chars for pin entry. Ravi_b3  . ATS BUG NO:11
    int size;

    do
    {
		// Array size increased to accomadate 12 chars for pin entry. Ravi_b3  . ATS BUG NO:11
        //size = inGetStringWithPrompt("Enter PIN: ", str, 12);
		size = inEnterWithMessage(EMV_ENTER_PIN_MSG, SCROLL_DISPLAY_FALSE, str,
	                             INPUT_ALNUMS_PWD, 12, NULL_PFI);
    } while (size < 4);

   	if( size == TRANS_CANCELLED)
	   		return (0);  // EMV Library expects a zero for transaction cancellation.Ravi_B3. 11/12/2002

	memcpy(pin, str, size);

    return (size);
    */

	unsigned short usLen;
	PFI_TO_GET_PIN pinGetUserPin; //Function pointer to EMV_GET_USER_PIN //K_F2
	short inResult = 0;
	char buff[256];

	 if(!inPinTried) {// This is the first Pin try
		 usEMVGetTLVFromColxn(TAG_9F17_PIN_TRY_COUNTER, &uchGblPinTryCtr, &usLen);
		 memset(buff, 0x00, sizeof(buff));
		 LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[TAG_9F17_PIN_TRY_COUNTER = 0x%X]", TAG_9F17_PIN_TRY_COUNTER, uchGblPinTryCtr));
	 }

	 if (inPinTried) {
 		vdDisplayMessageFromFile(EMV_INCORRECT_PIN_MSG, WARNING_MSG); // KK
	 }

	 if (uchGblPinTryCtr == 1)
		vdDisplayMessageFromFile(EMV_LAST_PIN_TRY_MSG, WARNING_MSG); // KK

	//Flush the keyboard buffer before prompting for PIN entry
	vdFlushKeyboardBuffer();

	//Change it to be overloadable by different region K_F2
	if ((pinGetUserPin = inGetFunctionPointer(EMV_GET_USER_PIN)) == NULL_PFI)
	{
		pinGetUserPin= inEnterWithMessage; //default function pointer is inEnterWithMessage
	}

	//vdDisplayAt_ASC8X21 (1, 4, "ENTER PIN ?      ", CLR_EOL );
	/*********************/
	inResult = pinGetUserPin (EMV_ENTER_PIN_MSG, SCROLL_DISPLAY_FALSE, (char *)pin,
                        INPUT_HIDE_NUMS, 10, inPINValidator);



	if (inResult == VS_ESCAPE)
	{
		//inResult = 0;	// No PIN entered so return PIN length of zero.
		inResult = E_USR_PIN_CANCELLED;
	}
	else if (inResult == 0)
	{
		inResult = E_USR_PIN_BYPASSED;
	}
	else
	{
		inPinTried = 1; // Pin entered
		uchGblPinTryCtr--;
	}
	return(inResult);
}

int inDefaultGetPTID(char *ptid)
{
    char    tempPTID [EMV_TERM_ID_SIZE + 2];

    SVC_INFO_PTID (tempPTID);
    strncpy (ptid, tempPTID+1, EMV_TERM_ID_SIZE);
    ptid[EMV_TERM_ID_SIZE+1] = 0x00;

    return (VS_SUCCESS);
}

int inEMVGetTermID(char * pchTermID)
{
 	//strcpy(pchTermID, srCPAC.szCPACTID, CPAC_TERM_ID_SIZE);
 	//strlcpy(pchTermID, "00000000", EMV_TERM_ID_SIZE); // To be modified to copy TID from the right table
 	strlcpy(pchTermID, (char *)szGetCPACTID(), EMV_TERM_ID_SIZE);
	return(VS_SUCCESS);
}

int inOnlinePINFunc(void)
{
    unsigned short len;
    srTxnResult TVRTSI;
    int retVal;

    char key[17];
    char binKey[8];
    byte track2[50];
    char track2Chars[101];

    usEMVGetTxnStatus(&TVRTSI);
    strcpy(key, "1234567890123456");
    ascii_to_bin((BYTE *)binKey, (BYTE *)key, 16);
    OnlinePIN((unsigned char *) binKey, 0, ADD_NEW_KEY);
    usEMVGetTLVFromColxn(0x5700, track2, &len);
    memset(track2Chars, 0, 101);
    hex_2_asc((byte *) track2Chars, track2, len);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5700, track2Chars));
    retVal=OnlinePIN((unsigned char *) track2Chars, 0, BUILD_PINBLOCK);       // Encrypted PIN block should be in track2
    if(retVal>0)
    {
    	ascii_to_bin(track2, (BYTE *)track2Chars, 16);
    	usEMVAddTLVToCollxn(0x9900, track2, 8);
    	TVRTSI.stTVR[2] |= 0x4;                 // Set bit in tvr for online PIN
    }
    else if(retVal==0)
	    TVRTSI.stTVR[2] |= 0x88;	// pin not entered, cardholder verification failed
    else
    	TVRTSI.stTVR[2] |= 0x90;	// pinpad not present or not working

	usEMVSetTxnStatus(&TVRTSI);

    return SUCCESS;
}

EMVBoolean bUpdateLogforSplitSales(void)
{

    char panStr[21] = {0};
	char panSeqStr[3] = {0};
	byte pan[10] = {0};
	byte panSeq[4] = {0};
	unsigned short len;
	int fHandle = 0;
	char RecStr[30] = {0};
	char *temp;

	char buf[200] = {0};
	long retVal =0;

	usEMVGetTLVFromColxn(0x5a00, pan, &len);
    hex_2_asc((byte *) stSpsales.panStr, pan, len);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5a00, stSpsales.panStr));

    while( (temp =  (char*)strrchr((char*)stSpsales.panStr,'F')) != NULL)
	stSpsales.panStr[temp - stSpsales.panStr] = 0;

	usEMVGetTLVFromColxn(0x5f34, panSeq, &len);
   	hex_2_asc((byte *) stSpsales.panSeqStr, panSeq, len);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5f34, stSpsales.panSeqStr));
	sprintf(stSpsales.trnAmt,"%ld",lnGlobalAmount);

	sprintf(RecStr,"%s,%s,%s\n\r",stSpsales.panStr,stSpsales.panSeqStr, stSpsales.trnAmt );

	fHandle = open ("splitsales.log",  O_CREAT | O_RDWR);

 	if(fHandle < 0)
 	    return(EMV_FALSE);

	lseek(fHandle, 0L, SEEK_SET);
	insert(fHandle, RecStr, strlen(RecStr));

	if ((retVal = lseek(fHandle,(long)(4L * sizeof(stSpsales)),SEEK_SET)) == (4 * sizeof(stSpsales)))
	{
		retVal = delete(fHandle,sizeof(stSpsales));
	}

	close(fHandle);
	return(SUCCESS);

}

unsigned long ulCheckSplitSalesAmt(void)
{

    char panStr[21] = {0};
	char panSeqStr[3] = {0};
	byte pan[10] = {0};
	byte panSeq[4] = {0};
	unsigned short len;
	int fHandle = 0;
	char RecStr[30] = {0};
	char buf[150] = {0};
	char * temp;
	unsigned short retVal;
	int noOfBytes = 0;
	char * pSeploc;
	char Amount[10];

	usEMVGetTLVFromColxn(0x5a00, pan, &len);
    hex_2_asc((byte *) panStr, pan, len);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5a00, panStr));

    while( (temp =  (char*)strrchr((char*)panStr,'F')) != NULL)
	panStr[temp - panStr] = 0;

	usEMVGetTLVFromColxn(0x5f34, panSeq, &len);
   	hex_2_asc((byte *) panSeqStr, panSeq, len);
	LOG_PRINTFF((0x08L, "TAG(0x%X): EMVGetTLV[??? = %s]", 0x5f34, panSeqStr));

	fHandle = open ("splitsales.log", O_RDONLY);

 	if(fHandle < 0)
 	    return(SUCCESS);

     memset(buf, 0x00, sizeof(buf));

     retVal = readRecord(fHandle, buf);

     //check for read() returning 0 for EOF.
     while(retVal != 0)
     {
             //get the card type
       //  noOfBytes = parseRecord(buf, 1, ',', temp);

		if( (pSeploc = strchr( buf, ',' )) != NULL)
		{
			memcpy(stSpsales.panStr,buf, (pSeploc-buf));
			memcpy(stSpsales.panSeqStr, &buf[pSeploc-buf+1],2);
			memcpy(stSpsales.trnAmt, &buf[pSeploc-buf+4],8);

			if( !(memcmp (panStr,stSpsales.panStr,strlen(panStr))))
				if( !(memcmp (panSeqStr,stSpsales.panSeqStr,strlen(panSeqStr))))
				{

					close (fHandle);
					return(atol(Amount));
				}
		}

         //CodeReview-18-Dec-2002
         //		Added this piece of code because the while loop would never end if
		//	    we didn't read the file again.
         retVal = readRecord(fHandle, buf);
         if(retVal == EMV_FALSE)
		 {
			 close (fHandle);
            return(SUCCESS);
		 }

     } //end of while

     close (fHandle);
	 return(SUCCESS);

}


/****************************************/
/* Call back functions for EMV library 			*/
/****************************************/
short getUsrPin(unsigned char *pin)
{
	short len = (short)E_PP_ABSENT;
	srTxnResult TVRTSI;

	usEMVGetTxnStatus(&TVRTSI);

    if (ppPresent)
    {
        clrscr();
        write_at("Wait for customer", 17, 1, 1);
        write_at("pin...", 6, 1, 2);
        if(inEMVPPPresent() == ROK)
        	len = (short) getPPUsrPin(pin, CKclear, CKencr, &masterKeyIndex);
        else
        	len = (short)E_PP_ABSENT;
    }
    else
       len = (short) getTermUsrPin(pin);
	pinStatus = len;
	pinSigRequired  = 0;

	return (len);
}

EMVResult getLastTxnAmt(Ulong *amt)
{
	*amt = 0L;

	*amt = ulCheckSplitSalesAmt();

	return (EMV_SUCCESS);
}

EMVResult usEMVIssAcqCVM(unsigned short issacq, unsigned short *code)
{
    return(EMV_SUCCESS);
}

unsigned short usEMVPerformOnlinePIN()
{
	clrscr();
	inOnlinePINFunc();
	write_at("PerformOnlinePin",16,1,inImamLineNumber);
	pinSigRequired  = 0;
	return (EMV_SUCCESS);
}

unsigned short usEMVPerformSignature()
{
	//clrscr();
	//vdClearNonTitleLines();
	//write_at("PerformSignature",16,1,8);
	// Global variable is set, which is used while printing the receipt.
	// The  global varible is set, for displaying signature required to the user and for printing.
	// ATS bug No. 17.  Ravi_B3
	pinSigRequired  = 1;
	return (EMV_SUCCESS);
}

void usEMVDisplayErrorPrompt(unsigned short errorID)
{
    char szMessage[MESSAGE_SIZE+1];

    memset(szMessage, 0x00, sizeof(szMessage));


	//clrscr();
	switch (errorID)
    {
	 case E_CAPK_FILE_NOT_FOUND:
	     //strcpy(msg, "CAPK FILE NOT FOUND");
	     vdGetMessageFromFile(CAPK_FILE_MISSING_MSG, szMessage);
            break;
        case E_INVALID_CAPK:
            //strcpy(msg, "INVALID CAPK");
            vdGetMessageFromFile(EMV_INVALID_CAPK_MSG, szMessage);
            break;
        case E_ICC_BLOCKED:
            //strcpy(msg, "ICC BLOCKED");
            vdGetMessageFromFile(EMV_ICC_BLKED_MSG, szMessage);
            break;
        case E_PIN_REQD:
            //strcpy(msg, "PIN REQD");
            vdGetMessageFromFile(EMV_PIN_REQD_MSG, szMessage);
            break;
        case E_LAST_PIN_TRY:
            //strcpy(msg, "LAST PIN TRY");
            vdGetMessageFromFile(EMV_LAST_PIN_TRY_MSG, szMessage);
            break;
        case E_PIN_TRY_LT_EXCEED:
            //strcpy(msg, "PIN TRY LT EXCEED");
            vdGetMessageFromFile(EMV_PIN_TRY_EXCD_MSG, szMessage);
            break;
        case E_USR_PIN_CANCELLED:
            //strcpy(msg, "PIN CANCELLED");
            vdGetMessageFromFile(EMV_PIN_CANCELLED_MSG, szMessage);
            break;
	case E_USR_PIN_BYPASSED:
            //strcpy(msg, "PIN BYPASSED");
            vdGetMessageFromFile(EMV_PIN_BYPASSED_MSG, szMessage);
            break;
	case 65364:
            //strcpy(msg, "PIN BLOCKED");  jrd spgalog066
            vdDisplayMessage("PIN BLOCKED", WARNING_MSG);
            break;
	default:
            //strcpy(msg, "WRONG PIN");
            vdGetMessageFromFile(EMV_WRONG_PIN_MSG, szMessage);
            break;
    }
    //write_at(szMessage, strlen(szMessage), 1, 8);
    vdDisplayAt(1, inImamLineNumber, szMessage, CLR_EOL);
    error_tone();
    vdDelay(PROMPT_DELAY);
}

void vdSetEMVOnlineCondition(TRANSACTION_OBJECT *pobTran, int inPipResult)
{

	if((EMV_CARD == pobTran->inChipStatus) && (EMV_GO_ONLINE == pobTran->inEMVCardDecision))
	{
		//For comm error
		if((inPipResult == PROT8583_FAILED_TRANSMIT) ||
			(inPipResult == PROT8583_CREATED_REVERSAL))
		{
			LOG_PRINTF(("FAILED TRANSMIT**************"));
			pobTran->inOnlineFailed = FAILED_TO_CONNECT;
			pobTran->srBRec.inTransactionResult  = FAILED_TO_CONNECT;
		}
		else if((inPipResult == HOST_ERROR) || (inPipResult == AMEX_VOICE_AUTH))
		{
			//Update response
			LOG_PRINTF(("HOST ERROR**************"));

			usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE , (byte *)srISO.pszField39, 2);
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = %s]", TAG_8A_AUTH_RESP_CODE, srISO.pszField39));

			if((strcmp((char*)srISO.pszField39, "01") == 0) /*||(strcmp((char*)srISO.pszField39, "02") == 0)*/)
			{

				//Do Referral Processing
				//pobTran->inEMVCardDecision = EMV_VOICE_REFERRAL;
            			pobTran->srBRec.inTransactionResult = HOST_REFERRAL;
			}
			else
				pobTran->srBRec.inTransactionResult = HOST_DECLINED;
		}
		else  if(inPipResult  == PIP_APPROVAL)//successful or decline transaction
		{

			LOG_PRINTF(("PIP APPROVAL**************"));
			pobTran->inOnlineFailed = EMV_COMMS_OK;

			//Update response
			usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE , (byte *)srISO.pszField39, 2);
			LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = %s]", TAG_8A_AUTH_RESP_CODE, srISO.pszField39));

			//inCPACPIPAnalyse will also set correct inTransactionResult
			if(!strcmp((char *)srISO.pszField39, "00"))
				pobTran->srBRec.inTransactionResult = HOST_AUTHORISED;
			else if((strcmp((char*)srISO.pszField39, "01") == 0) /*||(strcmp((char*)srISO.pszField39, "02") == 0)*/)
			{

				//Do Referral Processing
				//pobTran->inEMVCardDecision = EMV_VOICE_REFERRAL;
            			pobTran->srBRec.inTransactionResult = HOST_REFERRAL;
			}
			else
				pobTran->srBRec.inTransactionResult = HOST_DECLINED;

		}

	}

	return;

}


int inEMVReferralProcessing(TRANSACTION_OBJECT *pobTran)
{
#ifdef _TARG_68000
#else
	char chAnswer;
#endif
	int inResult;
	char szMessage[MESSAGE_SIZE + 1];
	unsigned char szTempBuf[2+1];

	memset(szMessage, 0x00, sizeof(szMessage));

	vdFlushKeyboardBuffer();

	if((pobTran->inEMVCardDecision == EMV_VOICE_REFERRAL) || (pobTran->srBRec.inTransactionResult == HOST_REFERRAL))
	{
		vdGetMessageFromFile(pobTran->srBRec.lnMessage, szMessage);
		vdDisplayAt(1,1, szMessage , NO_CLEAR);

		//if(pobTran->inEMVCardDecision == EMV_VOICE_REFERRAL)
		vdDisplayAt(1, inImamLineNumber-1, "REFERRAL", CLR_EOL);
		vdDisplayMessageFromFile(CALL_VOICE_CENTER_MSG, STATUS_MSG);

		inResult = inWaitKey(inGetIdleTimeOut());



		if (inResult == KEY_CANCEL)
		{

			memcpy(szTempBuf, EMV_CARD_REFERRAL_DECLINE, 2);
			pobTran->srBRec.inTransactionResult = HOST_DECLINED;

		}
		else
		{

			inResult = inRunFunction(pobTran, CPAC_GET_AUTH_CODE);

			if (inResult == VS_ESCAPE)
			{

				memcpy(szTempBuf, EMV_CARD_REFERRAL_DECLINE, 2);
				pobTran->srBRec.inTransactionResult = HOST_DECLINED;

			}
			else
			{
				
				pobTran->fReferral = VS_TRUE;
				/* LeeChyi - 13122005: Modified */
				/* Tag TAG_8A_AUTH_RESP_CODE should be for response code and not authorisation code.
					This is to fix ETEC test case REQ02 Mastercard Test 05 Scenario 01 */
				//memcpy(szTempBuf, pobTran->srBRec.szAuthCode, strlen(pobTran->srBRec.szAuthCode));
				memcpy(szTempBuf, srISO.pszField39, strlen((char *)srISO.pszField39));
				/* LeeChyi - END */
				pobTran->srBRec.inTransactionResult = HOST_AUTHORISED;
				 inStoreBatchFieldData(&pobTran->srBRec, CITI_EMV_BANK_REFFERAL, (unsigned char *)"TRUE", 5);

			}

		}

		//Update the response code in collection
		usEMVUpdateTLVInCollxn(TAG_8A_AUTH_RESP_CODE, szTempBuf,strlen((char *)szTempBuf));
		LOG_PRINTFF((0x08L, "TAG(0x%X): EMVUpdateTLV[TAG_8A_AUTH_RESP_CODE = %s]", TAG_8A_AUTH_RESP_CODE, szTempBuf));
	}

	return VS_SUCCESS;
}

/************************************************************************************************************

Function to capture the hot key press and set the Merchant Force Online flag to true

************************************************************************************************************/
int inEMVForceOnline(TRANSACTION_OBJECT *pobTran)
{
    char szTime[TIME_SIZE + 1];

    inLoadTCTRec(0);
    vdGetTime(szTime);
    vdSetForceOnLineTime(szTime);
    inSaveTCTRec(0);

    return VS_SUCCESS;

}

#if 0
int inEMVCheckForceOnline(TRANSACTION_OBJECT *pobTran)
{
	if(pobTran->srBRec.inChipStatus != 0)
	{
		char szCurrTime[TIME_SIZE + 1];
		char szForceOnlineTime[TIME_SIZE + 1];
		char szForceOnlineTimeOut[TIME_SIZE + 1];

		int inForceOnlineTimeOut, inTimeDiff;

		memset(szCurrTime, 0x00, sizeof(szCurrTime));
		memset(szForceOnlineTime, 0x00, sizeof(szForceOnlineTime));
		memset(szForceOnlineTimeOut, 0x00, sizeof(szForceOnlineTimeOut));

		strcpy(szForceOnlineTime, szGetForceOnLineTime());
		if(strlen(szForceOnlineTime) > 0)
		{
			vdGetTime(szCurrTime);
			inTimeDiff = inEMVGetTimeDiff(szCurrTime, szForceOnlineTime);

			get_env("EMV.TIMEOUT", szForceOnlineTimeOut, sizeof(szForceOnlineTimeOut));
			inForceOnlineTimeOut = atoi(szForceOnlineTimeOut);

			if(inLoadTCTRec(0) != VS_SUCCESS)
			{
			 	vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
			 	return VS_ERR;
			}

			if(inTimeDiff <= inForceOnlineTimeOut)
				vdSetEMVOnlineFlag(1);	//Set the merchant force online flag
			else
				vdSetEMVOnlineFlag(0);  //Reset the merchant force online flag

			if(inSaveTCTRec(0) != VS_SUCCESS)
			{
				vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
			 	return VS_ERR;
			}

			return VS_SUCCESS;
		}
		else
			return VS_SUCCESS;
	}
		return VS_SUCCESS;
}
#endif /* 0 */

int inEMVGetTimeDiff(char* pchTime1, char* pchTime2)
{
	char szTemp[TIME_SIZE+1];
	int inHH1, inHH2, inMM1, inMM2, inSS1, inSS2, inDiff;

		if ((strlen(pchTime1) == 0) || (strlen(pchTime2) == 0)) return (0); // No difference as the merchant is not

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime1[0], 2);
		inHH1 = atoi(szTemp);

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime1[2], 2);
		inMM1 = atoi(szTemp);

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime1[4], 2);
		inSS1 = atoi(szTemp);

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime2[0], 2);
		inHH2 = atoi(szTemp);

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime2[2], 2);
		inMM2 = atoi(szTemp);

		memset(szTemp, 0, sizeof(szTemp));
	       memcpy(szTemp, &pchTime2[4], 2);
		inSS2 = atoi(szTemp);


		inDiff = (((inHH1*60*60)+(inMM1*60)+inSS1) - ((inHH2*60*60)+(inMM2*60)+inSS2));

		if (inDiff < 0 ) inDiff *= (-1);

		return (inDiff);

}

int inEMVResetForceOnlineTime(TRANSACTION_OBJECT *pobTran)
{
	if(inLoadTCTRec(0) != VS_SUCCESS)
	{
		vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
		return VS_ERR;
	}

	vdSetForceOnLineTime("");

	if(inSaveTCTRec(0) != VS_SUCCESS)
	{
		vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
		return VS_ERR;
	}

	return VS_SUCCESS;

}

int inEMVSetAuthFloorLimit(TRANSACTION_OBJECT *pobTran)
{
	FLOOR_LIMIT = 0;

	return VS_SUCCESS;
}

/*********************************************************************************************
* @func short | inApplnESTVerifyAllCAPKs |
*		Read through all card scheme details and verify every CA Public Key file.
*		The same functonality is implemented in the EMV tool kit, but with out any error messages.
* 		So duplicating the functionality here inorder to display clear error messages.
* 		To get the results, this function needs to be called before inVXEMVAPSCInit() function of the Tool Kit. (else no effect)
* @parm short    |  VS_SUCCESS, VS_ERR	|
*
* @end
**********************************************************************************************/
int	inApplnESTVerifyAllCAPKs(void)
{
int     inRecNum = 0;
int     inFldNum, inRet;
int	 inKeyFound = 0;
char	szCAPKFileName[EMV_PK_FILE_NAME];
char	szCAPKExpDate[EMV_PK_EXPDATE_SIZE];		// PK Expiry date - not actually used here
int inDummyRec;
char szDummyFileName[EMV_PK_FILE_NAME + 1];

	inApplnCreateFileList(); // Will create a new Key List file if one does'nt already exists
	inApplnCheckAndCleanPKFiles(); // Will remove the unwanted CAPK files from the terminal

	while(1)
	{
	//	if (inLoadConfRec(EST_FILE_NAME, SIZE_EST_REC, inRecNum, (char *) &srESTRec) != VS_SUCCESS)
		if (inLoadESTRec(inRecNum) != VS_SUCCESS)
		{
			return(VS_SUCCESS);		// No more records in EST file
		}
		else
		{
			for (inFldNum = 1; inFldNum <= EST_NUM_OF_CAPKS; inFldNum++)
			{
				vdGetESTPKDataFile(szCAPKFileName, szCAPKExpDate, inFldNum);
				if (!strlen(szCAPKFileName))
					continue;

					inRet = inApplnESTVerifyCAPKFile(szCAPKFileName);

					if ((inRet == VS_ERR) || (inRet == VS_FAILURE))
					{	// Bad file
				   		vdClearNonTitleLines();
						vdClearTitleLine();
						if (inRet == VS_ERR)
					    		vdDisplayTitle(EMV_CORRUPT_CAPK_FILE, CENTER_JUSTIFY);
						else
							vdDisplayTitle(EMV_CAPK_FILE_MISSING_MSG, CENTER_JUSTIFY);

						vdDispStrCentered(szCAPKFileName, 3, CLR_EOL);
				   		vdDispMsgAtRight(EMV_PRESSANYKEY_MSG, 7, NO_CLEAR);

						ERR_BEEP();
						ERR_BEEP();

                    				inWaitKey( inGetIdleTimeOut());
					}
					else
					{
						if (inSearchConfRec(CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE, &inDummyRec, szDummyFileName,
															inApplnPKFIleNameCompFunc, szCAPKFileName) != VS_SUCCESS)
							inAppendConfRec (CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE, szCAPKFileName);
					}

			}

			inRecNum++;
		}
	}

}

/*********************************************************************************************
* @func short | inApplnCreateFileList |
*		Function used for CA PK revocation and cleaning.
*
* @parm short    |  VS_SUCCESS, VS_ERR	|
*
* @end
**********************************************************************************************/
int inApplnCreateFileList(void)
{
	int inNumRecs = 0;
	char szCAPKFileName[EMV_PK_FILE_NAME +1];

	memset(szCAPKFileName, 0, sizeof(szCAPKFileName));

	inNumRecs = inGetNumberOfConfRecs (CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE);

	if (inNumRecs == 0) // File could be absent or with 0 records.
		inAppendConfRec (CAPK_FILE_LIST_FILENAME, GEN_VER_SIZE, szCAPKFileName); //  Creating a new Key list file with a dummy info header of GEN_VER_SIZE

	return(VS_SUCCESS);
}

int inApplnPKFIleNameCompFunc (char* pszCAPKFileName1, char *pszCAPKFileName2)
{

	if (strcmp(pszCAPKFileName1, pszCAPKFileName2) != 0)
		return(VS_FALSE);
	return(VS_TRUE);
}

/*********************************************************************************************
* @func short | inApplnCheckAndCleanPKFiles |
* This function takes the file names of the CAPK files from the Files list and checks whether it exists in the new
* EST.DAT file. If it does'nt, removes the file from the terminal. This function will be called at startup so that it
* can be used for CAPK revocation and cleaning after every partial download of the Key files / EST.DAT.
*
* @parm short    |  VS_SUCCESS, VS_ERR	|
*
* @end
**********************************************************************************************/

int inApplnCheckAndCleanPKFiles(void)
{
	int inRecNo, inMaxRecs, inRecNum, inFldNum, inRet;
	CAPK_FILE_LIST_REC srFileListRec;
	int inFileFound;
	char	szCAPKFileName[EMV_PK_FILE_NAME];
	char	szCAPKExpDate[EMV_PK_EXPDATE_SIZE];

 	inMaxRecs = inGetNumberOfConfRecs (CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE);

 	for (inRecNo = 0; inRecNo < inMaxRecs; inRecNo++)
	{
		inFileFound = 0;
		if (inLoadConfRec (CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE, inRecNo, (char *) &srFileListRec) != VS_SUCCESS)
			break;

		inRecNum = 0;

	 	while(1)
		{
	//			if (inLoadConfRec(EST_FILE_NAME, SIZE_EST_REC, inRecNum, (char *) &srESTRec) != VS_SUCCESS)
			if (inLoadESTRec(inRecNum) != VS_SUCCESS)
				break;
			else
			{
				for (inFldNum = 1; inFldNum <= EST_NUM_OF_CAPKS; inFldNum++)
				{
					vdGetESTPKDataFile(szCAPKFileName, szCAPKExpDate, inFldNum);
					if (!strcmp(szCAPKFileName, srFileListRec.szCAPKFileName))
					{
						inFileFound = 1;
						break;
					}
				}
				if (inFileFound)
					break;  // Come out of while loop. Found one matchiing CAPK file in the EST.DAT
			}
			inRecNum++;
		}
	 	// Could not find that file name in the EST.DAT file. So delete it from the terminal
	 	if (!inFileFound)
	 	{
			inRet = remove(srFileListRec.szCAPKFileName);
			if (inDeleteConfRec (CAPK_FILE_LIST_FILENAME, FILE_LIST_FILENAME_SIZE, inRecNo) == VS_SUCCESS)
				inRecNo--; // Now one record has been deleted. So to read the next record, index has to be adjusted
	 	}
 	}

 	return(VS_SUCCESS);

}

/*********************************************************************************************
* @func short | inApplnESTVerifyCAPKFile |
*		Get the Certification Authority Public Key Modulus and the SHA1 20-byte check sum
*       (if it is there). Verify that the check sum value matches the hash value of the
*       Public Key Modulus.
*       Return value: VS_ERR means file has failed verification or has formatting error (i.e.
*       it must be corrupted somehow). VS_SUCCESS means no format error and key passes hash
*       validation if hash is present.
*
* @parm char * 	|  szCAPKFileName	|
*
* @parm int		|  VS_SUCCESS, VS_ERR	|
* @end
**********************************************************************************************/

int	inApplnESTVerifyCAPKFile(char *szCAPKFileName)
{
int  inFileHandle;
int  inASCIIKeyLen;
int  inASCIIExpLen;
int  inBytesRead;
char szASCIIHashBuff[40];
byte ucCompHashBuff[20];
byte ucKeyHashBuff[20];
char szExpBuff[EMV_MAX_PK_EXPONENT_SIZE];
char szModulusBuff[EMV_MAX_PK_MODULUS_SIZE];
byte ucModBuff[248];
unsigned long ulKeyLen;

	inFileHandle = open(szCAPKFileName, O_RDONLY);
	if (inFileHandle <= 0)
		return(VS_FAILURE); // File name exists, but file not found
		//return(VS_SUCCESS);	// No file so no bad key

	/* First read key length - this is 3 decimal digits */
	inBytesRead = read(inFileHandle, szModulusBuff, 3);
	if (inBytesRead != 3)
	{
		close(inFileHandle);
		return(VS_ERR);
	}
	szModulusBuff[3] = 0;
	inASCIIKeyLen = (atoi(szModulusBuff) * 2);

	/* Now read in all of the key - it is in hex digits */
	inBytesRead = read(inFileHandle, szModulusBuff, inASCIIKeyLen);
	if (inBytesRead != inASCIIKeyLen)
	{	// Bad file format
		close(inFileHandle);
		return(VS_ERR);
	}

	// Get Key Modulus in binary
	ascii_to_bin(ucModBuff, (byte *)szModulusBuff, inASCIIKeyLen);
	ulKeyLen = (unsigned long)(inASCIIKeyLen / 2);

   	/* Now read exponent length - this is 2 decimal digits */
	inBytesRead = read(inFileHandle, szExpBuff, 2);
	if (inBytesRead != 2)
	{	// Bad file format
		close(inFileHandle);
		return(VS_ERR);
	}
	szExpBuff[2] = 0;
	inASCIIExpLen = (atoi(szExpBuff) * 2);

	/* Now read in all of the exponent - it is in hex digits */
	inBytesRead = read(inFileHandle, szExpBuff, inASCIIExpLen);
	if (inBytesRead != inASCIIExpLen)
	{
		close(inFileHandle);
		return(VS_ERR);
	}

	/* Now read in the hash check sum - it is in hex digits */
	inBytesRead = read(inFileHandle, szASCIIHashBuff, 40);
	if (inBytesRead != 40)
	{
		close(inFileHandle);
		return(VS_SUCCESS);		// No hash so nothing to do
	}

	ascii_to_bin(ucKeyHashBuff, (byte *)szASCIIHashBuff, 40);

	// Now do the hash calculation on the key

	#ifdef _TARG_68000
    		G_SHA(ucCompHashBuff, ucModBuff, SHA_1, ulKeyLen);
	#endif /*  _TARG_68000  */

	#ifdef __arm
		SHA1(NULL, ucModBuff, ulKeyLen, ucCompHashBuff);
	#endif  /* __arm  */

	// Now do the comparison
	if (memcmp(ucKeyHashBuff, ucCompHashBuff, 20))
	{
		close(inFileHandle);
		return(VS_ERR);		// Bad hash value
	}

	close(inFileHandle);

	return(VS_SUCCESS);
}

int inEMVDisplaySigReqd(TRANSACTION_OBJECT *pobTran)
{
	char szMessageBuffer[MESSAGE_SIZE + 1];

	memset(szMessageBuffer, 0x00, sizeof(szMessageBuffer));

	 if(pobTran->srBRec.inChipStatus == EMV_CARD)
	 {
		 if (pinSigRequired)
		 {
		 	vdGetMessageFromFile(EMV_SIG_REQD_MSG, szMessageBuffer);
			vdClearNonTitleLines();
		 	vdDisplayAt(1,inImamLineNumber-3, szMessageBuffer, CLR_EOL);
		 	inWaitKey(5);
		 }
 	}

	return VS_SUCCESS;
}

void vdEMVSetFallbackTime(void)
{
	char szTime[TIME_SIZE + 1];

	inLoadTCTRec(0);
	vdGetTime(szTime);
	vdSetFallBackTime(szTime);
	inSaveTCTRec(0);
}

int inEMVResetFallBackTime(TRANSACTION_OBJECT *pobTran)
{
	if(inLoadTCTRec(0) != VS_SUCCESS)
	{
		vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
		return VS_ERR;
	}

	vdSetFallBackTime("");

	if(inSaveTCTRec(0) != VS_SUCCESS)
	{
		vdDisplayMessageFromFile(TCT_ERR_MSG21, ERROR_MSG);
		return VS_ERR;
	}

	return VS_SUCCESS;
}

int inEMVCheckTransAllwd(TRANSACTION_OBJECT *pobTran)
{

	if((lnTranTitleMessage != SALE_MSG) && (lnTranTitleMessage != AUTH_ONLY_ITEM_MSG15) &&
		(lnTranTitleMessage != PRE_AUTH_MSG)  && (lnTranTitleMessage != REFUND_OFFLINE_MSG) &&
		(lnTranTitleMessage != SALE_OFFLINE_MSG) && (lnTranTitleMessage != CITI_EPP_SALE_MSG) &&
		(lnTranTitleMessage != CITI_CARD_VERIFY_MSG) &&// jrd spqalog007 & spqalog012 // jrd 05212005
	    (lnTranTitleMessage != IMAM_CARDVER_MSG) &&
		(lnTranTitleMessage != IMAM_AUTHONLY_MSG)) //LIEM
		{
			vdDisplayMessageFromFile(TRANS_NOT_SUPPORTED_MSG, ERROR_MSG);
			LOG_PRINTFF((0x08L, "TRANSACTION NOT ALLOWED"));
			return VS_ERR;
		}
		else
			return VS_SUCCESS;

}

int inEMVCheckFallBackTime(TRANSACTION_OBJECT *pobTran)
{
	char szCurrTime[TIME_SIZE + 1];
	char szFallBackTime[TIME_SIZE + 1];
	char szFallBackTimeOut[TIME_SIZE + 1];

	int inFallBackTimeOut, inTimeDiff;
	LOG_PRINTFF((0x08L, "EMV_CHECK_FALLBACK_TIME = inEMVCheckFallBackTime ==============="));
	memset(szCurrTime, 0x00, sizeof(szCurrTime));
	memset(szFallBackTime, 0x00, sizeof(szFallBackTime));
	memset(szFallBackTimeOut, 0x00, sizeof(szFallBackTimeOut));

	inLoadTCTRec(0);

	strcpy(szFallBackTime, szGetFallBackTime());

	if (strlen(szFallBackTime) > 0) {
		vdGetTime(szCurrTime);
		inTimeDiff = inEMVGetTimeDiff(szCurrTime, szFallBackTime);

		get_env("EMV.TIMEOUT", szFallBackTimeOut, sizeof(szFallBackTimeOut));
		inFallBackTimeOut = atoi(szFallBackTimeOut);

		if(inTimeDiff > inFallBackTimeOut) {
			vdSetFallBackTime("");
			inSaveTCTRec(0);
			inLoadTCTRec(0);
			vdEMVSetICCReadFailure(VS_FALSE);
			LOG_PRINTFF((0x08L, "FALLBACK TIME is OVER"));
		}
	} 	
	LOG_PRINTFF((0x08L, "EMV_CHECK_FALLBACK_TIME = inEMVCheckFallBackTime =============== OK"));
	return VS_SUCCESS;
}

int inEMVCheckForceOnlineTime(TRANSACTION_OBJECT *pobTran)
	{
	char szCurrTime[TIME_SIZE + 1];
	char szForceOnlineTime[TIME_SIZE + 1];
	char szForceOnlineTimeOut[TIME_SIZE + 1];

	int inForceOnlineTimeOut, inTimeDiff;

	memset(szCurrTime, 0x00, sizeof(szCurrTime));
	memset(szForceOnlineTime, 0x00, sizeof(szForceOnlineTime));
	memset(szForceOnlineTimeOut, 0x00, sizeof(szForceOnlineTimeOut));

	inLoadTCTRec(0);

	strcpy(szForceOnlineTime, szGetForceOnLineTime());

	if(strlen(szForceOnlineTime) > 0)
	{
		vdGetTime(szCurrTime);
		inTimeDiff = inEMVGetTimeDiff(szCurrTime, szForceOnlineTime);

		get_env("EMV.TIMEOUT", szForceOnlineTimeOut, sizeof(szForceOnlineTimeOut));
		inForceOnlineTimeOut = atoi(szForceOnlineTimeOut);

		if(inTimeDiff > inForceOnlineTimeOut)
		{
			vdSetForceOnLineTime("");
			vdSetEMVOnlineFlag(0);  //Reset the merchant force online flag
			inSaveTCTRec(0);
			inLoadTCTRec(0);
			vdEMVSetICCReadFailure(VS_FALSE);
		}
		else
		{
			vdSetEMVOnlineFlag(1);	//Set the merchant force online flag
			inSaveTCTRec(0);
		}

		return VS_SUCCESS;
	}
	else
		return VS_SUCCESS;
}

//KiaSoon 04022006 Started: To fixed AEIPS APPL SELECT CASE EDR44
void vdResetApplLabel(void)
{
   inFirstSelect=1;
   memset(&srAPPLABEL,0x00,sizeof(LABEL_REC));
   return;	
}

void vdSetApplLabelSelect(int inLabel)
{
     //LOG_PRINTF(("vdSetApplLabelSelect"));
     srAPPLABEL.inApplSelected[inLabel-1]=1;
     srAPPLABEL.inMapLabel[inLabel-1]=-1;
     inFirstSelect=0;
     return;
}

void vdInitLabelTable(int inLabel)
{
     int i;
     //LOG_PRINTF(("vdInitLabelTable"));
     for(i=0; i<inLabel; i++)
     {
     	 srAPPLABEL.inOriginalLabel[i]=i+1;
     	 srAPPLABEL.inApplSelected[i]=0;
     	 srAPPLABEL.inMapLabel[i]=0;	
     }     
     
         
    /* for(i=0;i<inLabel; i++)
     {
     	LOG_PRINTFF((0x8L, "i=%d", (i+1)));
     	LOG_PRINTFF((0x8L, "vdInitLabelTable=%d",  srAPPLABEL.inOriginalLabel[i]));
     }*/
     
     return;
}

void vdGenerateMap(int inLabel)
{
     int i, j;
     for(i=0,j=0; i<inLabel; i++)
     {
     	if((srAPPLABEL.inApplSelected[i]!=1) && (srAPPLABEL.inMapLabel[i]!=-1))
     	{
     	   srAPPLABEL.inMapLabel[i]=j+1;
     	   j++;
     	}
     }
     /*
     for(i=0;i<inLabel; i++)
     {
     	LOG_PRINTFF((0x8L, "i=%d", (i+1)));
     	LOG_PRINTFF((0x8L, "inOriginalLabel=%d",  srAPPLABEL.inOriginalLabel[i]));
     	LOG_PRINTFF((0x8L, "inApplSelected=%d",   srAPPLABEL.inApplSelected[i]));
     	LOG_PRINTFF((0x8L, "inMapLabel=%d",srAPPLABEL.inMapLabel[i]));
     }*/			
     
     return;
}

int inRtrnMenuLabel(int inNumLabels)
{
	int i,j;
	for(i=0, j=0; i<inNumLabels; i++)
	{
	    if(srAPPLABEL.inApplSelected[i]==0)	    
	    	j++;
	}
	return j;
}

int inRtrnOriginalLabel(int inMapLabel)
{
	int i;
	for(i=0; i<MAX_APP_LABEL; i++)
	{
	    if(srAPPLABEL.inMapLabel[i]==inMapLabel) 
	        return (srAPPLABEL.inOriginalLabel[i]);
	}
	return VS_ERR;
}
//KiaSoon 04022006 Ended 